package org.pupil.config.consumer;

import org.pupil.annotation.RpcReference;
import org.pupil.common.URL;
import org.pupil.config.RpcProperties;
import org.pupil.event.RpcListerLoader;
import org.pupil.filter.FilterFactory;
import org.pupil.proxy.IProxy;
import org.pupil.proxy.ProxyFactory;
import org.pupil.register.RegistryFactory;
import org.pupil.register.RegistryService;
import org.pupil.router.LoadBalancerFactory;
import org.pupil.socket.client.Client;
import org.pupil.socket.compress.CompressFactory;
import org.pupil.socket.serialization.SerializationFactory;
import org.pupil.tolerant.FaultTolerantFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.Field;

/**
 * @Description: 服务发送方后置处理器
 * @Author: pupil
 * @Date: 2024/07/20 下午 8:58
 */
public class ConsumerPostProcessor implements BeanPostProcessor, InitializingBean {

    RpcProperties rpcProperties;

    public ConsumerPostProcessor(RpcProperties rpcProperties) {
        this.rpcProperties = rpcProperties;
    }


    // 设置属性后处理
    @Override
    public void afterPropertiesSet() throws Exception {
        new RpcListerLoader().init();
        FaultTolerantFactory.init();
        RegistryFactory.init();
        ProxyFactory.init();
        SerializationFactory.init();
        CompressFactory.init();
        FilterFactory.initClient();
        LoadBalancerFactory.init();
        final Client client = new Client();
        client.run();
    }

    // 每个bean初始化之前的操作
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 获取所有字段
        final Field[] fields = bean.getClass().getDeclaredFields();
        // 遍历所有字段找到 RpcReference 注解的字段
        for (Field field : fields) {
            if (field.isAnnotationPresent(RpcReference.class)) {
                final RegistryService registryService = RegistryFactory.get(rpcProperties.getRegistry().getName());
                // 字段的类class
                final Class<?> aClass = field.getType();
                final RpcReference rpcReference = field.getAnnotation(RpcReference.class);
                field.setAccessible(true);
                Object object = null;

                try {
                    // 创建代理对象
                    IProxy iProxy = ProxyFactory.get(rpcProperties.getProxy());
                    Object proxy = iProxy.getProxy(aClass, rpcReference);
                    object = proxy;
                    // 创建服务提供方的资源定位符
                    URL url = new URL();
                    url.setServiceName(aClass.getName());
                    url.setVersion(rpcReference.version());
                    // 进行服务订阅
                    registryService.subscribe(url);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    // 将代理对象设置给字段
                    field.set(bean, object);
                    field.setAccessible(false);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        return bean;
    }
}
